using CfgTable;
using DG.Tweening;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using UnityEngine;

namespace IQIGame.Onigao.GamePlay
{
    public class UIN_FloatNoticeItem : UIBaseNode
    {
        #region Template Generate,don't modify
        protected class UIB_UIN_FloatNoticeItem
        {
            #region ObjectBinding Generate
            public IQIGame.Onigao.Framework.ExArtSpriteNum bgQuality { protected set; get; }
            public UnityEngine.GameObject item { protected set; get; }
            public IQIGame.Onigao.Framework.ExText name { protected set; get; }
            public IQIGame.Onigao.Framework.ExText count { protected set; get; }
            public UnityEngine.CanvasGroup canvasGroup { protected set; get; }
            public virtual void InitBinding(ObjectBinding __binding)
            {
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExArtSpriteNum>("bgQuality", out var __tbv0);
                this.bgQuality = __tbv0;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("item", out var __tbv1);
                this.item = __tbv1;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExText>("name", out var __tbv2);
                this.name = __tbv2;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExText>("count", out var __tbv3);
                this.count = __tbv3;
                __binding.TryGetVariableValue<UnityEngine.CanvasGroup>("canvasGroup", out var __tbv4);
                this.canvasGroup = __tbv4;
            }
            #endregion ObjectBinding Generate 
        }
        #endregion Template Generate,don't modify

        #region fields
        private UIN_OneItem itemUnit = null;

        private System.Action callOnEndAnimationShow = null;
        private System.Action<UIN_FloatNoticeItem> callOnComplete = null;
        private CfgItem cfgItem = null;
        private int itemNum;
        private Vector3 localScaleFirst = new Vector3(0.9f, 0.5f, 1);
        private Vector3 localScaleChange = Vector3.one;
        private float changeAlpha = 0;
        #endregion fields

        #region properties

        protected UIB_UIN_FloatNoticeItem ui { get; set; }
        protected UIMsgDispatcher uiMsgDispatcher => this._msgDispatcher as UIMsgDispatcher;

        #endregion properties

        protected override void BeforeInit()
        {
            ui = new UIB_UIN_FloatNoticeItem();
            ui.InitBinding(this.csObjBind);
        }

        protected override void OnInit()
        {
            this.itemUnit = this.InitChildNode<UIN_OneItem>(this.ui.item);
        }

        protected override void OnShow()
        {

        }

        protected override void OnHide()
        {
            this.ClearData();
        }

        /// <summary>
        /// 添加UGUI侦听
        /// </summary>
        protected override void AddUGUIListener()
        {

        }

        /// <summary>
        /// 添加全局侦听（MsgDispatcher）
        /// </summary>
        protected override void AddMsgListeners()
        {

        }

        protected override void OnDispose()
        {
            this.ClearData();
        }

        #region methonds
        public void Show(int itemCid, int itemNum, System.Action<UIN_FloatNoticeItem> funcCall, System.Action funcOnEndAnimationShow)
        {
            this.SetData(itemCid, itemNum, funcCall, funcOnEndAnimationShow);
            this.Show();
            this.ui.canvasGroup.alpha = 1f;
            this.transform.SetAsFirstSibling();
            this.ShowItem();
            this.DoShowTween();
        }

        private void SetData(int itemCid, int itemNum, System.Action<UIN_FloatNoticeItem> funcCall, System.Action funcOnEndAnimationShow)
        {
            this.cfgItem = TableCenter.item.Get(itemCid);
            this.itemNum = itemNum;
            this.callOnEndAnimationShow = funcOnEndAnimationShow;
            this.callOnComplete = funcCall;
        }

        private void ClearData()
        {
            this.callOnComplete = null;
            this.callOnEndAnimationShow = null;

            this.cfgItem = null;
        }

        private void ShowItem()
        {
            this.itemUnit.Show(this.cfgItem);

            this.ui.name.text = this.cfgItem.Name;
            this.ui.count.text = " x" + this.itemNum;
            this.ui.bgQuality.SetInt(this.cfgItem.Quality);

            //this.ui.name.indexSwitchColor = this.cfgItem.Quality - 1;
            //this.ui.count.indexSwitchColor = this.cfgItem.Quality - 1;
        }

        private void DoShowTween()
        {
            float interval = APIUIConst.IntervalShowFloatNoticeItem;
            if (interval <= 0)
            {
                this.OnShowTweenComplete();
                return;
            }
            this.transform.localScale = localScaleFirst;
            this.localScaleChange = (Vector3.one - localScaleFirst) / interval;
            this.MakeAndPlayDoTween(interval, this.OnShowTweenComplete, this.OnShowTweenUpdate);
        }

        private void MakeAndPlayDoTween(float interval, TweenCallback callComplete, TweenCallback callUpdate = null)
        {
            var dt = DOTween.Sequence()
                .SetLink(this.gameObject)
                .SetTarget(this)
                .AppendInterval(interval);
            if (callUpdate != null)
                dt.OnUpdate(callUpdate);
            dt.OnComplete(callComplete);
            dt.Play();
        }

        private void OnShowTweenUpdate()
        {
            var localScale = this.transform.localScale + this.localScaleChange * Time.deltaTime;
            this.transform.localScale = localScale;
        }

        private void OnShowTweenComplete()
        {
            if (!this.IsAcived())
                return;
            this.transform.localScale = Vector3.one;
            this.ExecuteCallShowTweenComplete();
            this.DoTweenerDeltaHide();
        }

        private void ExecuteCallShowTweenComplete()
        {
            this.callOnEndAnimationShow?.Invoke();
        }

        private bool IsAcived()
        {
            return this.isActive;
        }

        private void DoTweenerDeltaHide()
        {
            float interval = APIUIConst.DeltaHideFloatNoticeItem;
            if (interval <= 0)
            {
                this.OnDeltaHideTweenComplete();
                return;
            }
            this.MakeAndPlayDoTween(interval, this.OnDeltaHideTweenComplete);
        }

        private void OnDeltaHideTweenComplete()
        {
            if (!this.IsAcived())
                return;
            this.DoTweenerHide();
        }

        private void DoTweenerHide()
        {
            float interval = APIUIConst.IntervalHideFloatNoticeItem;
            if (interval <= 0)
            {
                this.OnTweenHideComplete();
                return;
            }
            this.changeAlpha = 1.0f / interval;
            this.MakeAndPlayDoTween(interval, this.OnTweenHideComplete, this.OnTweenHideUpdate);
        }

        private void OnTweenHideUpdate()
        {
            if (!this.IsAcived())
                return;
            float val = this.ui.canvasGroup.alpha - this.changeAlpha * Time.deltaTime;
            val = Mathf.Max(val, 0);
            this.ui.canvasGroup.alpha = val;
        }

        private void OnTweenHideComplete()
        {
            if (!this.IsAcived())
                return;
            this.ExecuteCall();
        }

        private void ExecuteCall()
        {
            this.callOnComplete?.Invoke(this);
        }

        #endregion methonds
    }
}
